package cn.demomaster.quicktreeview;

import android.text.TextUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public class TreeData<T> {
    //原数据
    private List<T> data0;
    private TreeList data;

    public TreeData() {
    }

    public List getData() {
        return data;
    }

    private TreeDataConverter<T> dataConverter;

    /**
     * 数据源是List类型时 使用此方法
     *
     * @param data
     * @param converter
     */
    public void setListData(List<T> data, TreeDataConverter<T> converter) {
        data0 = data;
        dataConverter = converter;
        parseAsList(data);
    }

    /**
     * 数据源是树状结构类型时 使用此方法
     *
     * @param data
     * @param converter
     */
    public void setData(List<T> data, TreeDataConverter<T> converter) {
        data0 = data;
        dataConverter = converter;
        parseData(data);
    }

    private void parseAsList(List<T> data) {
        this.data = new TreeList();
        for (T item : data) {
            String id = dataConverter.getNodeId(item);
            String pid = dataConverter.getNodePid(item);
            String lable = dataConverter.getNodeLable(item);
            Object dataObj = dataConverter.getBindData(item);
            //Integer level = dataConverter2.getNodeLevel(item);
            TreeNode TreeNode = new TreeNode();
            TreeNode.setId(id);
            TreeNode.setLable(lable);
            TreeNode.setParentId(pid);
            TreeNode.bindData(dataObj);
            //TreeNode.setLevel(level);
            this.data.add(TreeNode);
        }
        this.data.sort();
    }

    private void parseData(List<T> data) {
        this.data = new TreeList();
        for (T item : data) {
            String id = dataConverter.getNodeId(item);
            String lable = dataConverter.getNodeLable(item);
            List<T> childs = dataConverter.getNodeChild(item);
            Object dataObj = dataConverter.getBindData(item);
            TreeNode TreeNode = new TreeNode();
            TreeNode.setId(id);
            TreeNode.setLable(lable);
            TreeNode.bindData(dataObj);
            TreeNode.setLevel(0);
            if (childs != null && childs.size() > 0) {
                parseTreeData(TreeNode, item);
            }
            this.data.add(TreeNode);
        }
        this.data.sort();
    }


    private void parseTreeData(TreeNode pNode, T data) {
        List<T> childs = dataConverter.getNodeChild(data);
        for (T item : childs) {
            String id = dataConverter.getNodeId(item);
            String lable = dataConverter.getNodeLable(item);
            List<T> childs1 = dataConverter.getNodeChild(item);
            Object dataObj = dataConverter.getBindData(item);
            TreeNode node = new TreeNode();
            node.setId(id);
            node.setLable(lable);
            node.bindData(dataObj);
            node.setLevel(pNode.getLevel() + 1);
            if (childs1 != null && childs1.size() > 0) {
                parseTreeData(node, item);
            }
            pNode.addChild(node);
        }
    }

    public static interface TreeDataConverter<T> {
        String getNodePid(T node);
        String getNodeId(T node);
        String getNodeLable(T node);
        Object getBindData(T node);
        List<T> getNodeChild(T node);
    }

    public static abstract class DataConverter<T> implements TreeDataConverter<T>{
        public TreeNode converToNode(T item){
            if(item!=null){
                String id = getNodeId(item);
                String lable = getNodeLable(item);
                Object dataObj = getBindData(item);
                TreeNode treeNode = new TreeNode();
                treeNode.setId(id);
                treeNode.setLable(lable);
                treeNode.bindData(dataObj);
            }
            return null;
        }
    }

//    public static interface TreeDataConverter2<T> {
//        String getNodePid(T node);
//
//        String getNodeId(T node);
//
//        String getNodeLable(T node);
//
//        List<T> getNodeChild(T node);
//
//        Integer getNodeLevel(T node);
//    }

    public static interface TreeItemData<T> {
        public String getId();

        public List<T> getChild();

        String getLable();
    }

    public static boolean isNotEmpty(String str) {
        if (!TextUtils.isEmpty(str)) {
            if (!str.trim().equals("null")) {
                return true;
            }
        }
        return false;
    }

    public static class TreeList extends ArrayList<TreeNode> {

        Map<String, Map> linkedHashMap = new LinkedHashMap();

        @Override
        public boolean add(TreeNode TreeNode) {
            boolean b;
            if (isNotEmpty(TreeNode.getParentId())) {
                b = addToParentNode(TreeNode);
            } else {
                b = super.add(TreeNode);
            }
            if (linkedHashMap.size() > 0) {
                boolean b1 = false;
                for (Map<String, TreeNode> map : linkedHashMap.values()) {
                    for (Map.Entry entry : map.entrySet()) {
                        b1 = addToParentNode((TreeNode) entry.getValue());
                    }
                }
                if (b1) {
                    b = true;
                }
            }
            return b;
        }

        /**
         * 添加到父节点
         *
         * @param node
         */
        private boolean addToParentNode(TreeNode node) {
            String pid = node.getParentId();
            TreeNode parentNode = findById(pid);
            if (parentNode != null) {
                node.setLevel(parentNode.getLevel() + 1);
                node.setParent(parentNode);
                parentNode.addChild(node);
                System.out.println("this=" + this);
                return true;
            } else {//父类还未添加  添加到未处理队列
                Map<String, TreeNode> map = linkedHashMap.get(pid);
                if (map == null) {
                    map = new HashMap<String, TreeNode>();
                }
                map.put(node.getId(), node);
                linkedHashMap.put(pid, map);
                return false;
            }
        }

        private TreeNode findById(String id) {
            for (TreeNode item : this) {
                if (item.getId().equals(id)) {
                    return item;
                } else if (item.getChild() != null) {
                    TreeNode TreeNode = findById(item, id);
                    if (TreeNode != null) {
                        return TreeNode;
                    }
                }
            }
            return null;
        }

        private TreeNode findById(TreeNode from, String id) {
            for (TreeNode item : from.getChild()) {
                if (item.getId().equals(id)) {
                    return item;
                } else if (item.getChild() != null) {
                    TreeNode TreeNode = findById(item, id);
                    if (TreeNode != null) {
                        return TreeNode;
                    }
                }
            }
            return null;
        }

        private void addChild(ArrayList arrayList, TreeNode TreeNode) {
            for (TreeNode item : TreeNode.getChild()) {
                arrayList.add(item);
                addChild(arrayList,item);
            }
        }
        public void sort() {
            ArrayList arrayList = new ArrayList();
            for (TreeNode item : this) {
                arrayList.add(item);
                addChild(arrayList,item);
            }
            this.clear();
            this.addAll(arrayList);
            // 使用Comparator接口自定义排序规则
//            Collections.sort(this, new Comparator<TreeNode>() {
//                @Override
//                public int compare(TreeNode s1, TreeNode s2) {
//                    if (TextUtils.isEmpty(s1.getParentId()) && !TextUtils.isEmpty(s1.getParentId())) {
//                        return 1;
//                    }
//                    return 1;
//                }
//            });
        }

    }

    /**
     * 过滤出所有可见的Node
     *
     * @param nodes
     * @return
     */
    public static List<TreeNode> filterVisibleNode(List<TreeNode> nodes) {
        List<TreeNode> result = new ArrayList<>();
        for (TreeNode node : nodes) {
            // 如果为跟节点，或者上层目录为展开状态
            if (node.isRoot() || node.isParentExpand()) {
                //setNodeIcon(node);
                result.add(node);
            }
        }
        return result;
    }

    public static List<TreeNode> filterExpandLevel(List<TreeNode> mAllNodes, int defaultExpandLevel) {
        if(mAllNodes!=null) {
            for (TreeNode node : mAllNodes) {
                // 如果为跟节点，或者上层目录为展开状态
                //setNodeIcon(node);
                node.setExpand(node.getLevel() <= defaultExpandLevel);
            }
        }
        return mAllNodes;
    }


//    public static void setfocusedNode(List<TreeNode> mNodes,String focusedId) {
//        for (TreeNode node : mNodes) {
//            // 如果为跟节点，或者上层目录为展开状态
//            if (node.getId().equals(focusedId)) {
//                node.setFocused(true);
//                return;
//            }else {
//                if(node.getChild()!=null){
//                    setfocusedNode(node.getChild(),focusedId);
//                }
//            }
//        }
//    }

}
